package com.atguigu.gulimall.search.thread;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 两任务组合-一个完成
 * 1、applyToEither：Function 带参有返回值【能获取前面任务的结果，自己有返回结果】【成功的那个任务的结果】
 * 2、acceptEither：Consumer 带参无返回值【能获取前面任务的结果，自己没有返回结果】
 * 3、runAfterEither：Runnable 无参无返回值【不能获取前面任务的结果，自己也没有返回结果】
 * 	supplyAsync：Supplier：无参有返回值【不能获取前面任务的结果，自己有返回值】
 * public <U> CompletableFuture<U> applyToEither(
 *     CompletionStage<? extends T> other, Function<? super T, U> fn) {
 *     return orApplyStage(null, other, fn);
 * }
 *
 * public <U> CompletableFuture<U> applyToEitherAsync(
 *     CompletionStage<? extends T> other, Function<? super T, U> fn) {
 *     return orApplyStage(asyncPool, other, fn);
 * }
 *
 * public <U> CompletableFuture<U> applyToEitherAsync(
 *     CompletionStage<? extends T> other, Function<? super T, U> fn,
 *     Executor executor) {
 *     return orApplyStage(screenExecutor(executor), other, fn);
 * }
 *
 * public CompletableFuture<Void> acceptEither(
 *     CompletionStage<? extends T> other, Consumer<? super T> action) {
 *     return orAcceptStage(null, other, action);
 * }
 *
 * public CompletableFuture<Void> acceptEitherAsync(
 *     CompletionStage<? extends T> other, Consumer<? super T> action) {
 *     return orAcceptStage(asyncPool, other, action);
 * }
 *
 * public CompletableFuture<Void> acceptEitherAsync(
 *     CompletionStage<? extends T> other, Consumer<? super T> action,
 *     Executor executor) {
 *     return orAcceptStage(screenExecutor(executor), other, action);
 * }
 *
 * public CompletableFuture<Void> runAfterEither(CompletionStage<?> other,
 *                                               Runnable action) {
 *     return orRunStage(null, other, action);
 * }
 *
 * public CompletableFuture<Void> runAfterEitherAsync(CompletionStage<?> other,
 *                                                    Runnable action) {
 *     return orRunStage(asyncPool, other, action);
 * }
 *
 * public CompletableFuture<Void> runAfterEitherAsync(CompletionStage<?> other,
 *                                                    Runnable action,
 *                                                    Executor executor) {
 *     return orRunStage(screenExecutor(executor), other, action);
 * }
 */

public class ThreadTest4 {
    public static ExecutorService excutor = Executors.newFixedThreadPool(10);

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        System.out.println("main start ....");

        CompletableFuture<Object> future1 = CompletableFuture.supplyAsync(()->{
            System.out.println("任务1 start..");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("任务1 end..");
            return 1+1;
        });

        CompletableFuture<String> future2 = CompletableFuture.supplyAsync(()->{
            System.out.println("任务2 start..");
            System.out.println("任务2 end..");
            return "hello";
        });

        // 两个任务都完成才执行任务3
//        CompletableFuture<String> future3 = future1.thenCombineAsync(future2, (result1, result2) -> {
//            return "任务3 ：组合前两个任务的返回值返回 --" + result1 + "---" + result2;
//        }, excutor);

        // 任一任务完成就可以执行任务3【返回值是future1的泛型】
        CompletableFuture<String> future3 = future1.applyToEitherAsync(future2, (result) -> {
            return "任务3 ：组合先执行完的任务的结果 --" + result;
        }, excutor);
        System.out.println("main end.... 返回值：" + future3.get());
    }
}
